//
// Created by Hoyin on 2024/4/15.
//

#include "PartiDetector.h"

template<> void PartiDetector<cv::ORB>::detect(const cv::Mat &src, std::vector <cv::KeyPoint> &keypoints) {
	_nFeatures = _detector->getMaxFeatures();
	_rois.clear();
	_keypoints.clear();
	_mask = cv::Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
	int h_len = cvRound(src.cols*1.0 / _hParts);
	int v_len = cvRound(src.rows*1.0 / _vParts);
	for (int v = 0; v < _vParts; v++) {
		int v_start = v*v_len;
		for (int h = 0; h < _hParts; h++) {
			int h_start = h*h_len;
			cv::Rect roi(h_start, v_start, h_len, v_len);
			while (roi.x + roi.width > src.cols) {
				roi.width--;
			}
			while (roi.y + roi.height > src.rows) {
				roi.height--;
			}
			_rois.push_back(roi);
		}
	}
//	std::cout << "ROIs: " << _rois.size() << std::endl;
	_detector->setMaxFeatures(int(_nFeatures / _rois.size()));
	for (const cv::Rect& roi : _rois) {
		cv::Mat iMask = _mask.clone();
		iMask(roi) = cv::Scalar(255);
		std::vector<cv::KeyPoint> kps;
		_detector->detect(src, kps, iMask);
		_keypoints.insert(_keypoints.end(), kps.begin(), kps.end());
//		std::cout << kps.size() << "/" << _detector->getMaxFeatures() << " keypoints has been detected in block (" << roi.x << ", " << roi.y << ", " << roi.width << ", " << roi.height << ")" << std::endl;
	}
	_detector->setMaxFeatures(int(_nFeatures));
	keypoints = _keypoints;
}
